import React from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
    ScrollView,
    StyleSheet,
    Platform,
    BackHandler,
    AppState,
    DeviceEventEmitter,
    NativeModules,
    Alert,
} from 'react-native';
import store from '@/store';
import { WebView } from 'react-native-webview';
import BaiduOcrScan from '../../../react-native-baidu-ocr-scan';
import StorageUtils from '@/utils/storageUtils';


import * as rootNavigation from '@/utils/rootNavigation';
import Toast from 'react-native-root-toast';
import NotifService from '../../../NotifService';
import { encode, decode } from 'base-64';
import FileViewer from 'react-native-file-viewer';
import RNFetchBlob from 'rn-fetch-blob';
import { withTranslation } from 'react-i18next';
import {
    APP_CODE as appCode,
    BASE_URL as baseURL,
    DEVICE_TYPE,
    APP_NAME as appName,
} from '../../../app.json';
import ReconnectingWebSocket from 'reconnecting-websocket';
import RFIDService from '@/utils/RFIDService';
import { useRoute } from '@react-navigation/native';

interface IState {
    auth: string | null;
    backButtonEnabled: boolean; //  true webview中返回
    hasGoLogin: boolean;
    user: any;
    rfidInitRes: boolean; //  true:初始化成功 false：初始化失败
}

interface IProps {
    navigation: any;
    route: any;
    userInfo: any;
}
let deviceType = DEVICE_TYPE || 'MOBILE';
let supportRfid = null;
let rfidEventParams = {};
const { PdaRFIDModule } = NativeModules;
class FormPage extends React.Component<IProps, IState> {
    constructor(props: IProps) {
        super(props);
        this.nav = this.props.navigation; //导航
        this.notif = new NotifService(
            this.onRegister.bind(this),
            this.onNotif.bind(this),
        );
        this.handleAppStateChange = this.handleAppStateChange.bind(this);
        this.connect = this.connect.bind(this);
        this.sendRfidResult = this.sendRfidResult.bind(this);
        this.init();
        this.subscription = null;
        this.inventoryTagListener = null; // 用于保存监听器
    }
    wssocket: any = null;
    serverUrl: string = '';
    notif: any = null;
    subscription: any = null;
    inventoryTagListener: any = null;
    rfidEventParams: any = null;
    state: IState = {
        auth: '',
        backButtonEnabled: false, // 判断网页是否可以回退
        hasGoLogin: false,
        user: store.getState().user.userInfo,
        rfidInitRes: false,
    };
    nav: any = null;
    webViewRef: any = null;
    init = () => {
        //  this.wssocket = null;
        const wsProtocal = baseURL.indexOf('https://') > -1 ? 'wss' : 'ws';
        try {
            const userId = this.state.user.user_id || '';
            const pattern = /^https?:\/\//;
            const formatUrl = baseURL.replace(pattern, '');
            this.serverUrl = `${wsProtocal}://${formatUrl}/ws/notice/androidNotice?userId=${userId}`;
        } catch (e) {
            console.log(e);
        }
    };

    initRfidAndCallback = async (
        callback = null,
        showToast = false,
        readEpc = false,
    ) => {
        if (supportRfid === false) {
            return;
        }
        if (supportRfid === null) {
            // 初始化
            try {
                RFIDService.initRFID(async (res: boolean) => {
                    this.setState({ rfidInitRes: res });
                    supportRfid = res;
                    if (res !== true) {
                        if (showToast) {
                            Toast.show('RFID初始化失败，请检查设备', {
                                duration: 1000,
                                position: Toast.positions.CENTER,
                            });
                        }
                        return;
                    }
                    if (readEpc && callback) {
                        callback();
                    }
                    // 注册事件监听器并保存返回的监听器对象
                    this.inventoryTagListener = await RFIDService.callbackRFID(res => {
                        if (!readEpc && callback) {
                            callback();
                        }
                        this.sendRfidResult(null, res);
                    });
                });
            } catch (e) {
                console.log('RFIDService.initRFID Fail', e);
            }
        }
    };

    //状态改变响应
    handleAppStateChange = appState => {
        if (appState === 'active') {
            this.initRfidAndCallback();
        } else if (appState === 'background') {
            try {
                RFIDService.disConnect();
                RFIDService.powerOFF();
            } catch (e) {
                console.log('RFIDService.powerOFF Fail', e);
            }
        }
    };

    componentDidMount(): void {
        const { navigation } = this.props;
        navigation.setOptions({
            headerShown: false,
            headerBackVisible: true,
        });
        this.connect();
        // 添加APP运行状态监听
        // 添加监听前，先移除之前的监听
        this.subscription = AppState.addEventListener(
            'change',
            this.handleAppStateChange,
        );
        store.subscribe(() => {
            const { lang } = store.getState();
            const currentLang = lang.lang;
            const result = {
                eventName: 'changeLang',
                langResult: currentLang,
            };
            if (this?.webViewRef?.postMessage) {
                this?.webViewRef?.postMessage(JSON.stringify(result));
            }
        });
        // 连接websocket
        this.getData();
        // this.init();
        BaiduOcrScan.addListener();

        // 添加返回键监听(对Android原生返回键的处理)
        this.addBackAndroidListener();
        this.notif = new NotifService(
            this.onRegister.bind(this),
            this.onNotif.bind(this),
        );
        supportRfid = null;
        this.initRfidAndCallback();
    }

    onLoadWebView = () => {
        const { lang } = store.getState();
        const currentLang = lang.lang;
        const result = {
            eventName: "changeLang",
            langResult: currentLang,
        };
        this.webViewRef?.postMessage(JSON.stringify(result));
    };

    componentWillUnmount() {
        if (this.wssocket?.close) {
            this.wssocket?.close();
            this.wssocket = null;
        }
        if (Platform.OS === 'android') {
            BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
        }
        BaiduOcrScan.removeListener();
        this.subscription?.remove();
        // 移除事件监听器
        if (this.inventoryTagListener) {
            this.inventoryTagListener?.remove(); // 确保调用 remove 方法
        }
    }
    connect = async () => {
        try {
            const auth = await StorageUtils.getItem('auth');
            const localUserId = auth?.user_id || '';
            const userId = this.state.user.user_id || localUserId;
            const pattern = /^https?:\/\//;
            const formatUrl = baseURL.replace(pattern, '');
            const wsProtocal = baseURL.indexOf('https://') > -1 ? 'wss' : 'ws';
            if (!userId) {
                this.wssocket?.close();
                return;
            }
            userId &&
                (this.serverUrl = `${wsProtocal}://${formatUrl}/ws/notice/androidNotice?userId=${userId}`);
            if (this.wssocket?.close) {
                await this.wssocket.close();
                this.wssocket = null;
            }
            this.wssocket = new ReconnectingWebSocket(this.serverUrl);
            this.wssocket.onopen = this.onOpen.bind(this);
            this.wssocket.onclose = this.onClose.bind(this);
            this.wssocket.onerror = this.onError.bind(this);
            this.wssocket.onmessage = this.onWsMessage.bind(this);
        } catch (e) {
            console.log('WebSocket err:', e);
        }
    };

    //发送消息
    sendMessage = msg => {
        if (this.wssocket && this.wssocket.readyState === WebSocket.OPEN) {
            try {
                this.wssocket.send(msg);
            } catch (err) {
                console.warn('ws sendMessage', err.message);
            }
        } else {
            console.log('WebSocket:', 'connect not open to send message');
        }
    };
    //打开连接
    onOpen() {
        console.log('WS_OPEN', this.serverUrl);
    }
    //关闭连接
    onClose(e) {
        console.log('WS_CLOSE', e);
    }
    //连接出错
    onError(e) {
        console.log('WS_ERROR::', e);
    }
    //接收消息
    onWsMessage = event => {
        try {
            const { message } = JSON.parse(event.data);
            const data = {
                title: `${appName}消息`,
                message: message,
                data: {
                    screen: 'Layout',
                },
            };
            this.notif.localNotif(data);
        } catch (e) {
            console.log('心跳消息', event.data);
        }
    };

    // 监听原生返回键事件
    addBackAndroidListener = () => {
        if (Platform.OS === 'android') {
            BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
        }
    };

    onBackAndroid = () => {
        if (this.state.backButtonEnabled) {
            if (this.webViewRef?.goBack) {
                this.webViewRef.goBack();
                return true;
            }
        }
        return false; //如果 WebView 无法后退，直接返回 `false` 取消事件
    };

    // 自定义返回事件--不用
    _goBackPage = () => {
        //  官网中描述:backButtonEnabled: false,表示webView中没有返回事件，为true则表示该webView有回退事件
        if (this.state.backButtonEnabled) {
            this.webViewRef.goBack();
        } else {
            //否则返回到上一个页面
            this.nav.goBack();
        }
    };
    onRefresh = () => {
        this.webViewRef.reload();
    };
    getDetailWebview = () => {
        /*
         * scrollEnabled:是否允许滚动
         * javaScriptEnabled 是否允许插入JS代码到webview里面
         * injectedJavaScript  插入到webview的<head></head>标签中的JS代码
         * onMessage:获取webview传过来的数据
         * source:这个部分可以是webview页面的url，也可以是直接的html代码
         * */

        const injectedJavascript = `(function() {
            function wrap(fn) {
                return function wrapper() {
                var res = fn.apply(this, arguments);
                window.ReactNativeWebView.postMessage('navigationStateChange');
                return res;
                }
            }
            history.pushState = wrap(history.pushState);
            history.replaceState = wrap(history.replaceState);
            window.addEventListener('popstate', function() {
                window.ReactNativeWebView.postMessage('navigationStateChange');
            });
            window.postMessage = function(data) {
                window.ReactNativeWebView.postMessage(data);
            };
            })()`;
    
        
        const queryStr = this.props.route?.params?.query;
        const queryAppCode = this.props.route?.params?.appCode;
   
        const { auth } = this.state;
        const appCodeBase64 = encode(queryAppCode || appCode);
        const pageUrl = `${baseURL}/${appCodeBase64}/mobileForm/formRuntime${queryStr}&auth=${auth}&deviceType=${deviceType}&firstLoad=true`;
        //  const pageUrl = `${baseURL}/${appCodeBase64}/workbench?auth=${auth}&deviceType=${deviceType}&firstLoad=true`;
        let webView_style = {};
        return (
            <WebView
                ref={ref => (this.webViewRef = ref)}
                originWhitelist={['*']}
                cacheEnabled={true}
                domStorageEnabled={true}
                style={webView_style}
                javaScriptEnabled={true}
                nestedScrollEnabled={false}
                injectedJavaScript={injectedJavascript}
                onNavigationStateChange={e => this.onNavigationStateChange(e)}
                source={{ uri: pageUrl }}
                onMessage={e => this.onMessage(e)}
                onLoadEnd={() => this.onLoadWebView()}
            ></WebView>
        );
    };

    getData = async () => {
        const auth = await AsyncStorage.getItem('auth');
        this.setState({
            auth: auth,
        });
    };

    // 原理是利用 webview 的 onNavigationStateChange 事件返回的canGoBack 属性，判断网页是否可以回退 ；
    //  如果可以回退就使用 webview.goBack() ; 如果不能回退就执行 navigator 的出栈操作。
    onNavigationStateChange = (navState: any) => {
        const canGoBack = navState.url?.indexOf('/mobileForm/formRuntime') < 0;
    };

    // 在RN端通过onMessage接收H5的消息
    onMessage = async (e: any) => {
        const { t } = this.props;
        let params = e.nativeEvent?.data;
        try {
            if (params === 'navigationStateChange') {
                const canGoBack = e.nativeEvent?.url?.indexOf('/mobileForm/formRuntime') < 0;
                this.setState({
                    backButtonEnabled: e.nativeEvent.canGoBack || canGoBack || false,
                });
                if (e.nativeEvent?.url?.indexOf('/mobileForm/formRuntime') > -1) {
                    this.nav.setOptions({
                        tabBarStyle: {
                            display: 'flex',
                            paddingTop: 6,
                            paddingBottom: 6,
                            height: 46,
                        },
                    });
                } else {
                    this.nav.setOptions({ tabBarStyle: { display: 'none' } });
                }
                // 这时记录下页面的可回退状态,然后通过ref获取该webview,调用它的goBack方法就可以了
            } else {
                try {
                    params = JSON.parse(params);
                } catch (e) { }
                if (params?.method === 'scanQrCode') {
                    this.callQRCode(params);
                } else if (params?.method === 'goBackPage') {
                    setTimeout(() => {
                        rootNavigation.replace(params.params);
                    }, 800)
                    // rootNavigation.navigate(params.params);
                } else if (params?.method === 'LOGOUT') {
                    // 监听退出登录的消息
                    await StorageUtils.removeItem('auth');
                    if (!this.state.hasGoLogin) {
                        this.setState({
                            hasGoLogin: true,
                        });
                    }
                    Toast.show(t('sys_tokenExpiredTip'), {
                        duration: 1000,
                        position: Toast.positions.CENTER,
                    });
                    rootNavigation.reset('Login');
                } else if (params?.method === 'filePreview') {
                    this.handleFilePreview(params.params);
                } else if (params?.method === 'rfidReadTag') {
                    if (supportRfid === false) {
                        supportRfid = null;
                    }
                    rfidEventParams = params;
                    const eventHandler = async () => {
                        // 上电
                        const powerRes = await PdaRFIDModule.powerAsync(true);
                        const connectRes = await NativeModules.PdaRFIDModule.connect();
                        RFIDService.inventorySingle((res: any) => {
                            // console.log('调用inventorySingle结果------', res);
                            // 方法调用成功：0；方法调用失败：-1
                        });
                    };
                    if (supportRfid === null) {
                        this.initRfidAndCallback(eventHandler, true, false);
                        return;
                    }
                    eventHandler();
                } else if (params?.method === 'rfidPowerOff') {
                    RFIDService.powerOFF();
                } else if (params?.method === 'rfidReadEpcTag') {
                    if (supportRfid === false) {
                        supportRfid === null;
                    }
                    const eventHandler = async () => {
                        // 上电
                        try {
                            const powerRes = await PdaRFIDModule.powerAsync(true);
                            const connectRes = await NativeModules.PdaRFIDModule.connect();
                            const { epc, btMemBank, btWordAdd, btWordCnt, strPassWord } =
                                params.params || {};
                            const res = await PdaRFIDModule.readTag(
                                epc,
                                btMemBank,
                                btWordAdd,
                                btWordCnt,
                                strPassWord,
                            );
                            this.sendRfidResult(params, res);
                        } catch (e) {
                            Toast.show('RFID读取标签失败' + e, {
                                duration: 1000,
                                position: Toast.positions.CENTER,
                            });
                        }
                    };
                    if (supportRfid === null) {
                        this.initRfidAndCallback(eventHandler, true, true);
                        return;
                    }
                    eventHandler();
                }
            }
        } catch (e) {
            // console.log('WebView onMessage 收到H5参数 error：', e);
        }
    };
    sendRfidResult = (params, res) => {
        // 发送标签数据到H5
        if (!params) {
            // params = this.rfidEventParams;
            params = rfidEventParams;
        }
        const result = {
            tagResult: res,
            ...params,
        };
        this?.webViewRef?.postMessage(JSON.stringify(result));
    };
    openFile = async (downloadDest: any) => {
        const { t } = this.props;
        FileViewer.open(downloadDest, { showOpenWithDialog: false })
            .then(() => {
                console.log('预览成功');
            })
            .catch(error => {
                Toast.show(t('sys_previeFileFailTip'), {
                    duration: 1000,
                    position: Toast.positions.CENTER,
                });
            });
    };
    handleFilePreview = async (params: any) => {
        const { t } = this.props;
        const { downloadUrl, fileId, fileName } = params;
        const fileIdUnique = fileId?.length ? fileId.substring(0, 6) : '';
        const fileUrl = downloadUrl.split(/[#?]/)[0].split('.');
        const extension = fileUrl.pop().trim();
        let fileNameRes = fileName;
        if (fileName) {
            const nameArr = fileName.split(/[#?]/)[0].split('.');
            if (nameArr?.length > 1) {
                nameArr.pop();
                fileNameRes = nameArr.join();
            }
        }

        if (!fileName) {
            const name = fileUrl.pop().split('/').pop().trim();
            fileNameRes = decodeURIComponent(name);
        }

        const downloadDest = `${RNFetchBlob.fs.dirs.DownloadDir}/${fileNameRes}-${fileIdUnique}.${extension}`;
        const exists = await RNFetchBlob.fs.exists(downloadDest); //判断文件里是否有该文件路径
        if (exists) {
            this.openFile(downloadDest);
            return;
        }
        Toast.show(t('sys_waitingFileDownload'), {
            duration: 1000,
            position: Toast.positions.BOTTOM,
        });
        RNFetchBlob.config({
            fileCache: true,
            addAndroidDownloads: {
                useDownloadManager: true,
                // notification: true,
                mediaScannable: true,
                title: `${fileNameRes}-${fileIdUnique}.${extension}`,
                path: downloadDest,
            },
        })
            .fetch('GET', downloadUrl, {})
            .then(res => {
                this.openFile(downloadDest);
            })
            .catch(error => {
                Toast.show(t('sys_fileDownloadFail'), {
                    duration: 1000,
                    position: Toast.positions.CENTER,
                });
            });
    };
    //   params  接收来自H5的参数，再回传
    callQRCode = (params: any) => {
        BaiduOcrScan.callQRCode((data: any) => {
            const result = {
                scanResult: data.data,
                ...params,
            };
            this.webViewRef.postMessage(JSON.stringify(result));
        });
    };

    onRegister(token) {
        // this.setState({registerToken: token.token, fcmRegistered: true});
    }
    onNotif() {
        // 点击消息后的的回调
        rootNavigation.navigate('message');
    }

    render() {
        return (
            <ScrollView
                style={styles.container}
                contentContainerStyle={styles.scrollView}>
                {this.getDetailWebview()}
            </ScrollView>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    tip: {
        paddingTop: 50,
    },
    scrollView: {
        flex: 1,
    },
    content: {
        flex: 1,
        // 隐藏 WebView 的滚动条
        overflow: 'hidden',
    },
    center: {
        textAlign: 'center',
    },
});

export default withTranslation()(FormPage);
